package model;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.table.AbstractTableModel;


import net.sf.image4j.codec.ico.ICODecoder;

public class FileTableModel extends AbstractTableModel implements TableModelListener{
	
	public FileTableModel(File root) {
		this.root = root;		
		icon = readImage("icons/Wcmicons_19.ico");	
		sdf = new SimpleDateFormat("HH:mm:ss MM-dd-yyyy");	
		
		//GlobalParams.getInstance().stringCollection.getDate_format();
	}
	
	@Override
	public String getColumnName(int arg0) {		
		return columnNames.get(arg0);
	}

	@Override
	public int getColumnCount() {		
		return columnNames.size();
	}

	@Override
	public int getRowCount() {		
		return data.size();
	}

	@Override
	public Object getValueAt(int arg0, int arg1) {		
		return data.get(arg0).get(arg1);
	}	
	
	public void setRoot(File r) {
		root = r ;		
	}	

	public File getSelectedRow(int i) {
		File file;
		try {
			file = (File) data.get(i).get(5);	
		} catch (Exception e) {
			file = null;			
		}		
		return file;
	}	
	
	public JLabel getSelectedRowName(int i) {
		return (JLabel) data.get(i).get(0);			
	}
	
	public String getParent() {
		return root.getParent();		
	}		
	
	
	
	public void Clear() {	
		Runnable r = new Runnable() {
			@Override
			public void run() {				
				data.clear();
			}			
		};		
		r.run();
		
	}	
	
	public ArrayList <ArrayList <Object > > genereteTable(final File file) {						
		ArrayList <ArrayList <Object > > temporaryData  = new ArrayList <ArrayList <Object > >();;
		//sdf = new SimpleDateFormat(GlobalParams.getInstance().stringCollection.getDate_format());	
		for (int fileInt = 0; fileInt < dataFiles.length ; fileInt++) {
			
			JFile tmp = new JFile(dataFiles[fileInt].getAbsolutePath(), File.pathSeparator.charAt(0) , '.');			
			FileSystemView view = FileSystemView.getFileSystemView();
			Icon img = view.getSystemIcon(dataFiles[fileInt].getAbsoluteFile());		    
			JLabel fileL = new JLabel(dataFiles[fileInt].getName());						  			
			fileL.setIcon(img);							
			
			ArrayList<Object> objects = new ArrayList<Object>();			
			if (!dataFiles[fileInt].isDirectory()) {				
				objects.add(fileL);
				objects.add(tmp.extension());
				objects.add(sdf.format(dataFiles[fileInt].lastModified()));
				objects.add(dataFiles[fileInt].getTotalSpace()/1024);
				objects.add(getAttr(dataFiles[fileInt]));
				objects.add(dataFiles[fileInt]);
				
			} else {				
				objects.add(fileL);
				objects.add("<DIR>");
				objects.add("");
				objects.add("");
				objects.add(getAttr(dataFiles[fileInt]));
				objects.add(dataFiles[fileInt]);
			}
			temporaryData.add(objects);					
		}
	
		return temporaryData;
	
	}
	
	
	public void Create(final File file) {
		
		Runnable r = new Runnable() {
			@Override
			public void run() {				
				root = file ;
				dataFiles = root.listFiles();	
				
				ArrayList <ArrayList <Object > > temporaryData  = genereteTable(file);					
				
				sortByExtensions(temporaryData,true);				
				
				if ( root.getParentFile() != null) {
					ArrayList<Object> object = new ArrayList<Object>();
					back = new JLabel("..");	
					back.setIcon(icon);
					object.add(back);
					object.add("");
					object.add("");
					object.add("");
					object.add("");
					object.add(root.getParentFile());			
					data.add(object);
				}
				
				if (temporaryData.size()>0) {
					for (int i=0 ; i<temporaryData.size();i++) {
						data.add(temporaryData.get(i));				
					}
				}		
			}			
		};		
		r.run();			
	}	
	
	public void UpdateNames() {
		columnNames.clear();		
		columnNames.add(GlobalParams.getInstance().stringCollection.getTable_file_name());
		columnNames.add(GlobalParams.getInstance().stringCollection.getTable_ext());
		columnNames.add(GlobalParams.getInstance().stringCollection.getTable_date());
		columnNames.add(GlobalParams.getInstance().stringCollection.getTable_size());
		columnNames.add(GlobalParams.getInstance().stringCollection.getTable_attr());	
		
		
	}	
	
	
	
	
	
	
	@SuppressWarnings({"unchecked", "rawtypes" })
	@Override	 
     public Class getColumnClass(int columnIndex) {	 
         if(columnIndex == 0)           	 
        	 return getValueAt(0, columnIndex).getClass(); 	 
         
         else 
        	 return super.getColumnClass(columnIndex);
   
     }
	 
	 @Override
     public boolean isCellEditable(int row, int column) {
         return false; 
     }
	 
	 public String getAttr(File f) {
			
		String attr = "";		
		
		if (f.canRead())
			attr += "r";
		else 
			attr += "-";
			
		if (f.canWrite())
			attr += "w";
		else 
			attr += "-";
		
		if (f.canExecute())
			attr += "x";
		else 
			attr += "-";
		
		return attr;		
	}
	 
	 public void sortByLastModyfication(Boolean is) {	
		 data.clear();
		 ArrayList <ArrayList <Object > > temporaryData  = genereteTable(root);			 
		 Collections.sort(temporaryData, new LastModyficationComparator(is));	
		 if ( root.getParentFile() != null) {
				ArrayList<Object> object = new ArrayList<Object>();
				back = new JLabel("..");	
				back.setIcon(icon);
				object.add(back);
				object.add("");
				object.add("");
				object.add("");
				object.add("");
				object.add(root.getParentFile());			
				data.add(object);
			}
			
			if (temporaryData.size()>0) {
				for (int i=0 ; i<temporaryData.size();i++) {
					data.add(temporaryData.get(i));				
				}
			}		
	}
	
	public void sortBySize( Boolean is) {	
		 data.clear();
		 ArrayList <ArrayList <Object > > temporaryData  = genereteTable(root);			 
		 Collections.sort(temporaryData, new SizeComparator(is));	
		 if ( root.getParentFile() != null) {
				ArrayList<Object> object = new ArrayList<Object>();
				back = new JLabel("..");	
				back.setIcon(icon);
				object.add(back);
				object.add("");
				object.add("");
				object.add("");
				object.add("");
				object.add(root.getParentFile());			
				data.add(object);
			}
			
			if (temporaryData.size()>0) {
				for (int i=0 ; i<temporaryData.size();i++) {
					data.add(temporaryData.get(i));				
				}
			}	 
	}
	
	public void sortByExtensions(Boolean is) {	
		 data.clear();
		 ArrayList <ArrayList <Object > > temporaryData  = genereteTable(root);			 
		 Collections.sort(temporaryData, new ExtensionsComparator(is));	
		 if ( root.getParentFile() != null) {
				ArrayList<Object> object = new ArrayList<Object>();
				back = new JLabel("..");	
				back.setIcon(icon);
				object.add(back);
				object.add("");
				object.add("");
				object.add("");
				object.add("");
				object.add(root.getParentFile());			
				data.add(object);
			}
			
			if (temporaryData.size()>0) {
				for (int i=0 ; i<temporaryData.size();i++) {
					data.add(temporaryData.get(i));				
				}
			}		 
	}
	
	public void sortByFileNames( Boolean is) {		
		 data.clear();
		 ArrayList <ArrayList <Object > > temporaryData  = genereteTable(root);			 
		 Collections.sort(temporaryData, new FileNamesComparator(is));	
		 if (root.getParentFile() != null) {
				ArrayList<Object> object = new ArrayList<Object>();
				back = new JLabel("..");	
				back.setIcon(icon);
				object.add(back);
				object.add("");
				object.add("");
				object.add("");
				object.add("");
				object.add(root.getParentFile());			
				data.add(object);
			}
			
			if (temporaryData.size()>0) {
				for (int i=0 ; i<temporaryData.size();i++) {
					data.add(temporaryData.get(i));				
				}
			}	  
	} 
	
	
	 
	public void sortByLastModyfication(ArrayList <ArrayList <Object > > data , Boolean is) {		 
		 Collections.sort(data, new LastModyficationComparator(is));					 
	}
	
	public void sortBySize(ArrayList <ArrayList <Object > > data , Boolean is) {		 
		 Collections.sort(data, new SizeComparator(is));					 
	}
	
	public void sortByExtensions(ArrayList <ArrayList <Object > > data , Boolean is) {		 
		 Collections.sort(data, new ExtensionsComparator(is));					 
	}
	
	public void sortByFileNames(ArrayList <ArrayList <Object > > data , Boolean is) {		 
		 Collections.sort(data, new FileNamesComparator(is));					 
	}
	
	public class LastModyficationComparator implements Comparator<ArrayList<Object>> {
		
		private Boolean desc;
		public LastModyficationComparator(Boolean d) {
			desc = d;
		}
		
	    @Override
	    public int compare(ArrayList <Object> o1, ArrayList <Object>o2) {		    	
	    	String t1 = (String)o1.get(2);
	    	String t2 = (String)o2.get(2);	
	    	if (desc == true)
	    		return t1.compareTo(t2);
	    	else 
	    		return t2.compareTo(t1);
	    }
	}
	 
	 public class SizeComparator implements Comparator<ArrayList<Object>> {
		private Boolean desc;
		public SizeComparator(Boolean d) {
			desc = d;
		}
		 
	    @Override
	    public int compare(ArrayList <Object> o1, ArrayList <Object>o2) {			    	
	    	String t1 = (String)o1.get(2);
	    	String t2 = (String)o2.get(2);		    	
	    	if (desc == true)
	    		return t1.compareTo(t2);
	    	else 
	    		return t2.compareTo(t1);	    		        
	    }
	}
	 
	 public class FileNamesComparator implements Comparator<ArrayList<Object>> {
		private Boolean desc;
		public FileNamesComparator(Boolean d) {
				desc = d;
		}
		
	    @Override
	    public int compare(ArrayList <Object> o1, ArrayList <Object>o2) {
	    	JLabel time1 = (JLabel)o1.get(0);
            JLabel time2 = (JLabel)o2.get(0);
            if (desc == true)
            	return time2.getText().compareTo(time1.getText());	
	    	else 
	    		return time1.getText().compareTo(time2.getText());	
            	    	        
	    }
	}	 
	 public class ExtensionsComparator implements Comparator<ArrayList<Object>> {
		private Boolean desc;
		
		public ExtensionsComparator(Boolean d) {
				desc = d;
		}
	    
		@Override
	    public int compare(ArrayList <Object> o1, ArrayList <Object>o2) {		    	
	    	String t1 = (String)o1.get(1);
	    	String t2 = (String)o2.get(1);		    	
	    	if (desc == true)
	    		return t1.compareTo(t2);
	    	else 
	    		return t2.compareTo(t1);		        
	    }
	}
	 
	 private ImageIcon readImage(String filename) {			
			InputStream inIcon = ClassLoader.getSystemResourceAsStream(filename);
			try {				
				java.util.List<BufferedImage> image = ICODecoder.read(inIcon);
				ImageIcon tmp = new ImageIcon(image.get(0));
				return tmp;
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;		
	}
	 
	@Override
	public void tableChanged(TableModelEvent arg0) {
		fireTableChanged(arg0);
		
	}
	
	private static final long serialVersionUID = 1L;	
	private ArrayList <String> columnNames = new ArrayList <String>();	
	SimpleDateFormat sdf;	
	private ArrayList <ArrayList <Object > > data  = new ArrayList <ArrayList <Object > >();
	private File[] dataFiles;
	private File root;
	private JLabel back;
	private ImageIcon icon;
	
	

}
